package show.me.the.money.configure;

import java.io.File;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import show.me.the.money.config.schema.Schema;
import show.me.the.money.config.schema.SchemaController;
import show.me.the.money.configure.base.IConfig;
import show.me.the.money.dictionary.Dictionaries;
import show.me.the.money.util.xml.XMLHelper;


@SuppressWarnings("unchecked")
public class SchemaConfig extends IConfig {

	public Document dic(){
		return SchemaController.instance().convertToDictionaryXML();
	}
	
	public HashMap<String, Object> save(LinkedHashMap<String, Object> map){
		String parent = (String) map.get("parentId");
		String id = (String) map.get("id");
		String alias = (String) map.get("alias");
		if(!StringUtils.isEmpty(SchemaController.instance().getConfigFilename(id))){
			return setCode(450, "file exists", null);
		}
		String path = SchemaController.instance().getConfigFilename(id, parent);
		Document doc = DocumentHelper.createDocument();
		Element define = doc.addElement("entry").addAttribute("id", id).addAttribute("alias", alias);
		List<HashMap<String, Object>> items = (List<HashMap<String, Object>>) map.get("items");
		for(HashMap<String, Object> m:items){
			Element item = define.addElement("item");
			for(String k:m.keySet()){
				Object o = m.get(k);
				if(o == null || StringUtils.isEmpty(String.valueOf(o))){
					continue;
				}
				if("dic".equals(k)){
					item.addElement("dic").addAttribute("id", String.valueOf(o));
				}else if("dicRender".equals(k)){
					Element itemDic = item.element("dic");
					if(itemDic != null){
						itemDic.addAttribute("render", String.valueOf(o));
					}
				}else{
					item.addAttribute(k, String.valueOf(o));
				}
			}
		}
		XMLHelper.putDocument(new File(path), doc);
		Dictionaries.instance().reload("schemalist");
		return setCode(200, "success", null);
	}
	
	public HashMap<String, Object> update(LinkedHashMap<String, Object> map){
//		String parent = (String) map.get("parentId");
		String id = (String) map.get("id");
		String alias = (String) map.get("alias");
		Document doc = SchemaController.instance().getConfigDoc(id);
		Element define = doc.getRootElement();
		define.addAttribute("alias", alias);
//		List<Element> els = define.elements("item");
		List<HashMap<String, Object>> items = (List<HashMap<String, Object>>) map.get("items");
		removeItem(define, items);
		for(HashMap<String, Object> m:items){
			String itemId = (String) m.get("id");
			if(StringUtils.isEmpty(itemId)){
				continue;
			}
			Element item = (Element) define.selectSingleNode("item[@id='"+itemId+"']");
			if(item == null){
				item = define.addElement("item");
			}
			for(String k:m.keySet()){
				Object o = m.get(k);
				if(o == null || StringUtils.isEmpty(String.valueOf(o))){
					continue;
				}
				if("dic".equals(k)){
					Element dic = item.element("dic");
					if(dic != null){
						item.remove(dic);
					}
					item.addElement("dic").addAttribute("id", String.valueOf(o));
				}else if("dicRender".equals(k)){
					Element dic = item.element("dic");
					if(dic != null){
						dic.addAttribute("render", String.valueOf(o));
					}
				}else{
					item.addAttribute(k, String.valueOf(o));
				}
			}
		}
		XMLHelper.putDocument(new File(SchemaController.instance().getConfigFilename(id)), doc);
		SchemaController.instance().reload(id);
		Dictionaries.instance().reload("schemalist");
		return setCode(200, "success", null);
	}
	
	public HashMap<String, Object> remove(String id){
		String filename = SchemaController.instance().getConfigFilename(id);
		if(StringUtils.isEmpty(filename)){
			return setCode(450, "file is not exists", null);
		}
		File file = new File(filename);
		file.delete();
		Dictionaries.instance().reload("schemalist");
		return setCode(200, "success", null);
	}
	
	private void removeItem(Element define,List<HashMap<String, Object>> items){
		List<Element> els = define.elements("item");
		Iterator<Element> it = els.iterator();
		while(it.hasNext()){
			Element e = it.next();
			String eId = e.attributeValue("id");
			if(StringUtils.isEmpty(eId)){
				continue;
			}
			boolean needRemove = true;
			for(HashMap<String, Object> m:items){
				String itemId = (String) m.get("id");
				if(StringUtils.isEmpty(itemId)){
					continue;
				}
				if(itemId.equals(eId)){
					needRemove = false;
					break;
				}
			}
			if(needRemove){
				it.remove();
			}
		}
	}
	
	public HashMap<String, Object> addFolder(String parent){
		
		return null;
	}
	
	public HashMap<String, Object> load(String id){
		Schema sc = SchemaController.instance().getSchema(id);
		if(sc != null){
			HashMap<String, Object> schema = sc.data();
			if(schema.containsKey("items")){
				List<HashMap<String, Object>> items = (List<HashMap<String, Object>>) schema.get("items");
				for(Iterator<HashMap<String, Object>> it=items.iterator();it.hasNext();){
					HashMap<String, Object> si = it.next();
					if(si.containsKey("dic")){
						HashMap<String, String> d = (HashMap<String, String>) si.get("dic");
						if("1".equals(d.get("internal"))){
							si.remove("dic");
							continue;
						}
						si.put("dic", d.get("id"));
						String render = d.get("render");
						if(render != null){
							si.put("dicRender", render);
						}
					}
				}
			}
			return setCode(200, "success", schema);
		}
		return setCode(404, "schema missing", null);
	}
	
}
